home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
netconf
/
ppp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-05
|
22KB
|
901 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include "../misc/confdb.h"
#include "netconf.h"
#include "../userconf/userconf.h"
#include "../paths.h"
#include "netconf.m"
static char ATZOK[]="ATZ OK ATDT";
#define TYPE_PPP_LOGIN 0
#define TYPE_PPP_PAP 1
#define TYPE_PPP_CHAP 2
#define TYPE_SLIP 3
#define TYPE_PLIP1 4
#define TYPE_PLIP2 5
static NETCONF_HELP_FILE help_ppp ("ppp");
static CONFIG_FILE f_ppp (ETC_PPP_CONF_PPP
,help_ppp
,CONFIGF_OPTIONNAL|CONFIGF_MANAGED
,"root","root",0600);
// File used to store argument of pppd
static CONFIG_FILE f_pppargs (VAR_RUN_PPPD_ARGS
,help_ppp
,CONFIGF_GENERATED
,"root","root",0600);
static CONFIG_FILE f_ppp0 (VAR_RUN_PPP0_PID
,help_ppp
,CONFIGF_OPTIONNAL
,"root","root",0600);
/* #Specification: PPP & SLIP / management
All configuration information is store in the file
/etc/ppp/conf.ppp. This file is a CONFDB file, with
the same format as /etc/conf.linuxconf.
The information for all channels are stored in this file
There are record identifying the channels
#
.channel name1
.channel name2
#
And then, for each channel
#
name1.login login
name1.passwd password
name1.phone phone
#
and so on.
*/
struct LK_STR{
const char *key;
SSTRING *str;
const char *defval;
};
struct LK_INT{
const char *key;
int *num;
int defval;
};
struct LK_CHAR{
const char *key;
char *num;
char defval;
};
class PPPONE{
SSTRING name; // Symbolic name of the configuration
SSTRING phone;
SSTRING login;
SSTRING passwd;
SSTRING loginkey; // String required before sending login
// Normally ogin:
SSTRING passwdkey; // String required before sending the password
// Normally assword:
SSTRING loginok; // optionnal confirmation string
// telling the passwd was good
SSTRING loginfail; // optionnal string identifying a login failure
// (password was wrong)
SSTRING loginchat; // Custom login chat in case the standard one
// fail.
SSTRING device;
SSTRING modeminit;
char type; // TYPE_xxxx
char defaultroute;
char modem; // Modem controls
char lock; // Set standard lock file
char proxyarp; // Establish proxyarp when connecting
int mru;
int mtu;
int baud;
int idletime;
char dbgppp;
char dbgchat;
SSTRING options; // pppd options which are not
// handled by this program
SSTRING asyncmap; // One specific important option of
// pppd
SSTRING ourip; // Optionnal IP numbers
SSTRING remoteip;
SSTRING lcpecho;
LK_STR strs[20];
LK_INT nums[20];
LK_CHAR chars[20];
/*~PROTOBEG~ PPPONE */
public:
PPPONE (CONFDB&cfg, const char *_name);
int connect (int fore);
private:
int connect_plip (void);
int connect_ppp (int fore);
int connect_slip (int);
protected:
void del (CONFDB&cfg, const char *_name);
public:
int disconnect (void);
private:
int disconnect_plip (void);
public:
int disconnect_ppp (void);
private:
int disconnect_slip (void);
public:
int edit (CONFDB&cfg);
private:
int lcpecho_parse (int &delay, int &retry);
int lcpecho_valid (void);
public:
int save (CONFDB&cfg);
private:
void setuptbdb (void);
public:
/*~PROTOEND~ PPPONE */
};
static char CHANNEL[]="channel";
static char PHONE[]="phone";
static char LOGIN[]="login";
static char PASSWD[]="passwd";
static char LOGINKEY[]="loginkey";
static char PASSWDKEY[]="passwdkey";
static char LOGINOK[]="loginok";
static char LOGINFAIL[]="loginfail";
static char LOGINCHAT[]="loginchat";
static char DEVICE[]="device";
static char MODEMINIT[]="modeminit";
static char TYPE[]="type";
static char LOCK[]="lock";
static char MODEM[]="modem";
static char DEFAULTROUTE[]="defaultroute";
static char PROXYARP[]="proxyarp";
static char MRU[]="mru";
static char MTU[]="mtu";
static char BAUD[]="baud";
static char IDLETIME[]="idletime";
static char DBGPPP[]="dbgppp";
static char DBGCHAT[]="dbgchat";
static char OPTIONS[]="options";
static char ASYNCMAP[]="asyncmap";
static char OURIP[]="ourip";
static char REMOTEIP[]="remoteip";
static char LCPECHO[]="lcpecho";
/*
Initialise 3 tables to simplify loading/clearing and saving
*/
PRIVATE void PPPONE::setuptbdb()
{
memset (strs,0,sizeof(strs));
memset (chars,0,sizeof(chars));
memset (nums,0,sizeof(nums));
strs[0].key = PHONE;
strs[0].str = ☎
strs[1].key = LOGIN;
strs[1].str = &login;
strs[2].key = PASSWD;
strs[2].str = &passwd;
strs[3].key = DEVICE;
strs[3].str = &device;
strs[4].key = MODEMINIT;
strs[4].str = &modeminit;
strs[4].defval = ATZOK;
strs[5].key = OPTIONS;
strs[5].str = &options;
strs[6].key = ASYNCMAP;
strs[6].str = &asyncmap;
strs[6].defval = "0";
strs[7].key = OURIP;
strs[7].str = &ourip;
strs[8].key = REMOTEIP;
strs[8].str = &remoteip;
strs[9].key = LOGINOK;
strs[9].str = &loginok;
strs[10].key = LOGINCHAT;
strs[10].str = &loginchat;
strs[11].key = LOGINFAIL;
strs[11].str = &loginfail;
strs[12].key = LOGINKEY;
strs[12].str = &loginkey;
strs[12].defval = "ogin:--ogin:";
strs[13].key = PASSWDKEY;
strs[13].str = &passwdkey;
strs[13].defval = "assword:";
strs[14].key = LCPECHO;
strs[14].str = &lcpecho;
strs[14].defval = "";
strs[15].key = NULL;
chars[0].key = TYPE;
chars[0].num = &type;
chars[0].defval = 0;
chars[1].key = MODEM;
chars[1].num = &modem;
chars[1].defval = 1;
chars[2].key = DEFAULTROUTE;
chars[2].num = &defaultroute;
chars[2].defval = 1;
chars[3].key = LOCK;
chars[3].num = &lock;
chars[3].defval = 1;
chars[4].key = DBGPPP;
chars[4].num = &dbgppp;
chars[4].defval = 0;
chars[5].key = DBGCHAT;
chars[5].num = &dbgchat;
chars[5].defval = 0;
chars[6].key = PROXYARP;
chars[6].num = &proxyarp;
chars[6].defval = 0;
chars[7].key = NULL;
nums[0].key = BAUD;
nums[0].num = &baud;
nums[0].defval = 38400;
nums[1].key = MRU;
nums[1].num = &mru;
nums[1].defval = 1500;
nums[2].key = IDLETIME;
nums[2].num = &idletime;
nums[2].defval = 0;
nums[3].key = MTU;
nums[3].num = &mtu;
nums[3].defval = 0;
nums[4].key = NULL;
}
PUBLIC PPPONE::PPPONE(CONFDB &cfg, const char *_name)
{
setuptbdb();
#if 0
type = 0;
baud = 38400;
lock = 1;
mru = 1500;
mtu = 0;
modem = 1;
idletime = 0;
proxyarp = 0;
modeminit.setfrom (ATZOK);
defaultroute = 1;
dbgppp = 0;
dbgchat = 0;
asyncmap.setfrom ("0");
#endif
if (_name != NULL){
name.setfrom (_name);
for (LK_STR *ps = strs; ps->key != NULL; ps++){
ps->str->setfrom (cfg.getval(_name,ps->key
,ps->defval));
}
for (LK_INT *pn = nums; pn->key != NULL; pn++){
*pn->num = cfg.getvalnum(_name,pn->key
,pn->defval);
}
for (LK_CHAR *pc = chars; pc->key != NULL; pc++){
*pc->num = cfg.getvalnum(_name,pc->key
,pc->defval);
}
}else{
for (LK_STR *ps = strs; ps->key != NULL; ps++){
ps->str->setfrom (ps->defval);
}
for (LK_INT *pn = nums; pn->key != NULL; pn++){
*pn->num = pn->defval;
}
for (LK_CHAR *pc = chars; pc->key != NULL; pc++){
*pc->num = pc->defval;
}
}
}
/*
Update the CONFDB object and save it on disk
*/
PUBLIC int PPPONE::save(CONFDB &cfg)
{
const char *_name = name.get();
SSTRINGS lst;
cfg.getall ("",CHANNEL,lst,1);
if (lst.lookup(name.get())==-1){
lst.add (new SSTRING(name));
cfg.replace ("",CHANNEL,lst);
}
for (LK_STR *ps = strs; ps->key != NULL; ps++){
cfg.replace (_name,ps->key,*ps->str);
}
for (LK_INT *pn = nums; pn->key != NULL; pn++){
cfg.replace (_name,pn->key,*pn->num);
}
for (LK_CHAR *pc = chars; pc->key != NULL; pc++){
cfg.replace (_name,pc->key,*pc->num);
}
return cfg.save();
}
/*
Remove this configuration from the configuration file
*/
PROTECTED void PPPONE::del(CONFDB &cfg, const char *_name)
{
if (_name[0] != '\0'){
SSTRINGS lst;
cfg.getall ("",CHANNEL,lst,1);
int pos = lst.lookup(_name);
if (pos != -1){
lst.remove_del (lst.getitem(pos));
cfg.replace ("",CHANNEL,lst);
}
for (LK_STR *ps = strs; ps->key != NULL; ps++){
cfg.removeall (_name,ps->key);
}
for (LK_INT *pn = nums; pn->key != NULL; pn++){
cfg.removeall (_name,pn->key);
}
for (LK_CHAR *pc = chars; pc->key != NULL; pc++){
cfg.removeall (_name,pc->key);
}
}
}
/*
Check if the configuration name exist
*/
static int ppp_exist (CONFDB &cfg, const SSTRING &name)
{
SSTRINGS lst;
cfg.getall ("",CHANNEL,lst,0);
return lst.lookup(name.get()) != -1;
}
/*
Add a baud rate field in a dialog with standard values
*/
void baud_setfield (
int baud,
SSTRING &baudstr,
DIALOG &dia)
{
char msg[10];
baudstr.setfrom (baud);
FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_BAUD,"Baud rate"),baudstr);
static short int tb[]={
3,6,12,24,48,96,
192,384,576,1152
};
for (unsigned i=0; i<sizeof(tb)/sizeof(tb[0]); i++){
sprintf (msg,"%d00",tb[i]);
comb->addopt (msg);
}
}
void serial_setfield (
SSTRING &device,
DIALOG &dia)
{
FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_SERIALDEF
,"Serial device"),device);
comb->addopt ("/dev/cua0",MSG_U(F_FIRSTCOM,"first standard serial port COM1"));
comb->addopt ("/dev/cua1",MSG_U(F_SECONDCOM,"Second standard serial port COM2"));
comb->addopt ("/dev/ttyS0",MSG_U(F_COM1M,"COM1 when using mgetty"));
comb->addopt ("/dev/ttyS1",MSG_U(F_COM2M,"COM2 when using mgetty"));
}
/*
Parse the lcpecho field (delay,retry).
Return -1 if any error, 0 if empty, 1 if a value pair is supplied
*/
PRIVATE int PPPONE::lcpecho_parse(int &delay, int &retry)
{
int ret = -1;
delay = retry = 0;
if (lcpecho.is_empty()){
ret = 0;
}else{
const char *str = lcpecho.get();
delay = atoi(str);
const char *pt = strchr(str,',');
if (pt != NULL){
retry = atoi(pt+1);
if (delay != 0 && retry != 0) ret = 1;
}
}
return ret;
}
PRIVATE int PPPONE::lcpecho_valid()
{
int d,r;
return lcpecho_parse (d,r)!=-1;
}
PUBLIC int PPPONE::edit (CONFDB &cfg)
{
int ret = -1;
DIALOG dia;
SSTRING oldname (name);
dia.newf_str (MSG_U(F_PPPNAME,"Configuration name"),name);
dia.newf_radio (MSG_U(F_CONNECTTYPE,"Connection type"),type
,TYPE_PPP_LOGIN
,MSG_U(F_PPPLOGIN,"PPP using normal login account"));
dia.newf_radio ("",type,TYPE_PPP_PAP
,MSG_U(F_PPPPAP,"PPP using PAP authentication"));
dia.newf_radio ("",type,TYPE_PPP_CHAP
,MSG_U(F_PPPCHAP,"PPP using CHAP authentication"));
dia.newf_radio ("",type,TYPE_SLIP,MSG_U(F_SLIP,"SLIP"));
dia.newf_radio ("",type,TYPE_PLIP1
,MSG_U(F_PLIP1,"PLIP1 (IP over printer port 1)"));
dia.newf_radio ("",type,TYPE_PLIP2
,MSG_U(F_PLIP2,"PLIP2 (IP over printer port 2)"));
dia.newf_str (MSG_U(F_OURIP,"Our IP number(opt)"),ourip);
dia.newf_str (MSG_U(F_REMOTEIP,"Remote IP number(opt)"),remoteip);
dia.newf_title ("",MSG_U(T_LOGINCHAT,"Login chat"));
dia.newf_str (MSG_U(F_LOGINKEY,"Expected login key"),loginkey);
dia.newf_str (MSG_U(F_LOGIN,"login"),login);
dia.newf_str (MSG_U(F_PASSWDKEY,"Expected password key"),passwdkey);
dia.newf_str (MSG_U(F_PASSWORD,"Password"),passwd);
dia.newf_str (MSG_U(F_LOGINOK,"Expected welcome (opt)"),loginok);
dia.newf_str (MSG_U(F_LOGINFAIL,"Login fail key (opt)"),loginfail);
dia.newf_str (MSG_U(F_LOGINCHAT,"Custom login chat (opt)"),loginchat);
dia.newf_title ("",MSG_U(T_MODEM,"Modem specifications"));
serial_setfield (device,dia);
dia.newf_str (MSG_U(F_MODEMCHAT,"Modem initialisation"),modeminit);
dia.newf_str (MSG_U(F_PHONE,"Phone"),phone);
dia.newf_chk ("",modem,MSG_U(F_MODEMCTRL,"Modem controls"));
dia.newf_chk ("",lock,MSG_U(F_LOCKFILE,"Lock file"));
SSTRING baudstr;
baud_setfield (baud,baudstr,dia);
dia.newf_title ("",MSG_U(T_FEATURES,"Features"));
dia.newf_chk ("",defaultroute,MSG_U(F_DEFROUTE,"Default route"));
dia.newf_chk ("",proxyarp
,MSG_U(F_PROXYARP,"Proxy Arp (fake remote on local net)"));
dia.newf_num (MSG_U(F_IDLETIME,"Idle time"),idletime);
dia.newf_num (MSG_U(F_PPPMRU,"PPP MRU"),mru);
dia.newf_num (MSG_U(F_PPPMTU,"PPP MTU(opt)"),mtu);
dia.newf_chk ("",dbgppp,MSG_U(F_RUNPPPD,"Run pppd in debug mode"));
dia.newf_chk ("",dbgchat,MSG_U(F_RUNCHAT,"Run chat in debug mode"));
dia.newf_str (MSG_U(F_ASYNCMAP,"Async map"),asyncmap);
FIELD_COMBO *cecho = dia.newf_combo (MSG_U(F_LCPECHO,"LCP echo"),lcpecho);
cecho->addopt ("",MSG_U(F_NOLCPECHO,"Don't use LCP echo protocol"));
cecho->addopt ("15,3",MSG_U(F_ECHO15_3,"Send lcp echo every 15, hangup after 3 failures"));
dia.newf_str (MSG_U(F_OTHERPPP,"Other PPP options"),options);
int no = 0;
int extra_but = name.is_empty() ? 0 : MENUBUT_DEL;
while (1){
char title[100];
sprintf (title,MSG_U(T_ONEPPPCONF,"%s PPP/SLIP configuration")
,name.is_empty() ? MSG_U(T_NEWPPP,"new") : name.get());
MENU_STATUS code = dia.edit (title
,MSG_U(I_ONEPPPCONF,"One PPP, SLIP or PLIP configuration")
,help_ppp
,no
,extra_but|MENUBUT_ACCEPT|MENUBUT_CANCEL);
if (code == MENU_CANCEL || code == MENU_ESCAPE){
break;
}else if (code == MENU_ACCEPT){
char buferr[2000];
buferr[0] = '\0';
baud = baudstr.getval();
if (!oldname.is_empty() && name.cmp(oldname)!=0){
if (ppp_exist (cfg,name)){
sprintf (buferr
,MSG_U(E_DUPCONF,"The configuration %s\n"
"already exist\n"
"Use another name\n\n")
,name.get());
}
}
if (name.is_empty()){
strcat (buferr,MSG_U(E_NEEDNAME,"You must supply\n"
"a configuration name\n\n"));
}
if (device.is_empty()
&& type != TYPE_PLIP1
&& type != TYPE_PLIP2){
strcat (buferr,MSG_U(E_NEEDDEV,"You must supply "
"a device (/dev/xxxx)\n\n"));
}
if (!lcpecho_valid ()){
strcat (buferr,MSG_U(E_LCPECHO,"You must supply a value pair\n"
" delay,retry for the LCP echo protocol"));
}
if (buferr[0] != '\0'){
xconf_error (buferr);
}else{
del(cfg,oldname.get());
save (cfg);
ret = 0;
break;
}
}else if (code == MENU_DEL){
if (xconf_yesno(MSG_U(Q_DELETED,"Are you sure")
,MSG_U(I_DELETED,"This configuration will be\n"
"deleted permanently")
,help_ppp)){
dia.restore();
del(cfg,oldname.get());
cfg.save();
ret = 0;
break;
}
}
}
return ret;
}
static void strcat_b (char *chat, const SSTRING &str)
{
strcat (chat," ");
strcat (chat,str.get());
}
/*
Establish the PPP connection
*/
PRIVATE int PPPONE::connect_ppp(int fore)
{
/* #Specification: ppp / pppd and chat
All argument to pppd and chat are passed using file
instead of command line argument. They can't be seen
using ps -ax.
*/
char path[PATH_MAX];
sprintf (path,"%s.%s",f_pppargs.getpath(),name.get());
FILE *fargs = f_pppargs.fopen (path,"w");
if (fargs != NULL){
DAEMON *cmd_chat = daemon_find ("chat");
DAEMON *cmd_pppd = daemon_find ("pppd");
if (cmd_chat != NULL && cmd_pppd != NULL){
char chat[1000];
strcpy (chat,"ABORT 'NO CARRIER' ABORT BUSY '' ");
strcat (chat,modeminit.get());
strcat (chat,phone.get());
strcat (chat," CONNECT");
fprintf (fargs,"%s\n",options.get());
if (!asyncmap.is_empty()){
fprintf (fargs,"asyncmap %s\n",asyncmap.get());
}
if (type == TYPE_PPP_LOGIN){
if (!loginchat.is_empty()){
loginchat.copy (chat);
}else{
strcat (chat," ''");
strcat_b (chat,loginkey);
strcat_b (chat,login);
strcat_b (chat,passwdkey);
strcat_b (chat,"\\q");
strcat (chat,passwd.get());
if (!loginfail.is_empty()){
// If we see loginfail, this means that the login
// sequence did fail, so we abort right away
// instead of falling in pppd and receving all
// kind of meaningless messages (pppd believes
// it is talking to another pppd).
strcat (chat," ABORT");
strcat_b (chat,loginfail);
}
if (!loginok.is_empty()){
strcat_b (chat,loginok);
}
}
}else if (type == TYPE_PPP_PAP){
fprintf (fargs,"+pap user %s\n",login.get());
}else if (type == TYPE_PPP_CHAP){
fprintf (fargs,"+chap user %s\n",login.get());
}
if (dbgppp){
fputs ("-d -d\n",fargs);
}
if (lock) fputs ("lock\n",fargs);
if (modem){
fputs ("modem crtscts\n",fargs);
}
fprintf (fargs,"mru %d\n",mru);
if (mtu != 0) fprintf (fargs,"mtu %d\n",mtu);
fprintf (fargs,"%s:%s\n",ourip.get(),remoteip.get());
if (idletime != 0){
fprintf (fargs,"idle-disconnect %d\n",idletime);
}
if (defaultroute) fputs ("defaultroute\n",fargs);
if (proxyarp) fputs ("proxyarp\n",fargs);
if (fore) fputs ("-detach\n",fargs);
{
int d,r;
if (lcpecho_parse (d,r)==1){
fprintf (fargs,"lcp-echo-interval %d lcp-echo-failure %d\n"
,d,r);
}
}
char pathchat[PATH_MAX];
sprintf (pathchat,"%s-chat.%s",f_pppargs.getpath(),name.get());
FILE *fchat = f_pppargs.fopen (pathchat,"w");
if (fchat != NULL){
fprintf (fargs,"connect '%s %s -f %s'\n"
,cmd_chat->getpath()
,dbgchat ? "-v" : ""
,pathchat);
fprintf (fchat,"%s\n",chat);
fclose (fchat);
fprintf (fargs,"%s\n",device.get());
fprintf (fargs,"%d\n",baud);
fclose (fargs);
dialog_end();
fflush (stdout);
setuid (geteuid());
/* #Specification: netconf / --connect / --fore
When connecting a PPP link with the --fore
option, linuxconf sleep for 5 seconds
before calling pppd. Generally this
option is used to establish a permanent
link by calling netconf from inittab.
The sleep give some chance to the
getty/mgetty process to initialise the
modem properly before launching another
pppd.
When using the --fore option, netconf
just pass control to pppd with the
-detach option. netconf does not stay
in memory.
*/
if (fore) sleep(5);
execl (cmd_pppd->getpath(),cmd_pppd->getpath()
,"file",path,NULL);
}else{
fclose (fargs);
}
}
}
return -1;
}
/*
Terminate the PPP connection
*/
PUBLIC int PPPONE::disconnect_ppp()
{
/* #Specification: ppp / disconnecting
The support for disconnection is weak, as it kills
the first ppp connexion (ppp0) without checking.
Although this is fine for simple setup, it is not
acceptable.
We must find a way to get the pid of the pppd process
and stores it in our own pid file. The problem is that
pppd fork at one point so we don't know the final
pid. Maybe an option is needed (or already available)
in pppd to set the pid file name. This would solve the
problem.
*/
int ret = -1;
FILE *fin = f_ppp0.fopen ("r");
if (fin != NULL){
int pid;
fscanf (fin,"%d",&pid);
ret = kill (pid,SIGTERM);
fclose (fin);
}
return ret;
}
/*
Initialise a PLIP link
*/
PRIVATE int PPPONE::connect_plip()
{
int ret = -1;
char buf[100];
const char *plipdev = type == TYPE_PLIP1 ? "plip1" : "plip2";
sprintf (buf,"%s %s pointopoint %s",plipdev
,ourip.get(),remoteip.get());
if (netconf_system_if ("ifconfig",buf) != -1){
sprintf (buf,"add %s %s",remoteip.get(),plipdev);
if (netconf_system_if ("route",buf) != -1){
if (!defaultroute){
ret = 0;
}else{
sprintf (buf,"add default %s",plipdev);
if (netconf_system_if ("route",buf) != -1){
ret = 0;
}
}
}
}
return ret;
}
/*
Terminate a PLIP link
*/
PRIVATE int PPPONE::disconnect_plip()
{
char buf[100];
const char *plipdev = type == TYPE_PLIP1 ? "plip1" : "plip2";
sprintf (buf,"%s down",plipdev);
return netconf_system_if ("ifconfig",buf);
}
PRIVATE int PPPONE::connect_slip(int)
{
xconf_error (MSG_U(E_ONLYPPP,"Only normal PPP is supported yet!"));
return -1;
}
PRIVATE int PPPONE::disconnect_slip()
{
xconf_error (MSG_R(E_ONLYPPP));
return -1;
}
/*
Establish the PPP/SLIP/PLIP connection
*/
PUBLIC int PPPONE::connect(
int fore) // Don't go in background
{
int ret;
if (type == TYPE_PLIP1 || type == TYPE_PLIP2){
ret = connect_plip();
}else if (type == TYPE_SLIP){
ret = connect_slip(fore);
}else{
ret = connect_ppp(fore);
}
return ret;
}
/*
Disconnect the PPP/SLIP/PLIP connection
*/
PUBLIC int PPPONE::disconnect()
{
int ret;
if (type == TYPE_PLIP1 || type == TYPE_PLIP2){
ret = disconnect_plip();
}else if (type == TYPE_SLIP){
ret = disconnect_slip();
}else{
ret = disconnect_ppp();
}
return ret;
}
void ppp_edit ()
{
static const char *msg = MSG_U(P_CONFPPP,"configure PPP and SLIP");
if (perm_rootaccess(msg)){
CONFDB cppp (f_ppp);
int choice = 0;
while (1){
SSTRINGS lst;
int nb = cppp.getall ("",CHANNEL,lst,0);
lst.sort();
DIALOG dia;
for (int i=0; i<nb; i++){
dia.new_menuitem (" ",*lst.getitem(i));
}
dia.addwhat (MSG_U(I_ADDCONF,"a new configuration"));
MENU_STATUS code = dia.editmenu(
MSG_U(T_PPPCONF,"PPP/SLIP configuration")
,MSG_U(I_PPPCONF,"You are allowed to edit/add\n"
"PPP and SLIP configuration\n"
"which will allow your computer to connect\n"
"to PPP and SLIP server")
,help_ppp
,choice
,0);
const char *sel = dia.getmenustr(choice);
if (code == MENU_ESCAPE || code == MENU_QUIT){
break;
}else if (perm_rootaccess(msg)){
if (code == MENU_ADD){
PPPONE one (cppp,NULL);
one.edit (cppp);
}else if (sel != NULL){
if (code == MENU_OK){
PPPONE one (cppp,sel);
one.edit (cppp);
}
}
}
}
}
}
static PPPONE *ppp_getconfig (int argc, char *argv[])
{
PPPONE *ret = NULL;
if (perm_rootaccess("activate a network link")){
CONFDB cppp (f_ppp);
if (argc == 1){
const char *name = argv[0];
if (ppp_exist (cppp,name)){
ret = new PPPONE (cppp,name);
}else{
xconf_error (MSG_U(E_NOCONF,"No configuration %s"),name);
}
}
}
return ret;
}
/*
Establish a PPP/SLIP connnection
*/
int ppp_connect (int argc, char *argv[])
{
int ret = -1;
int fore = 0;
if (argc == 2){
argc--;
if (strcmp(argv[1],"--fore")==0){
fore = 1;
}else{
xconf_error (MSG_U(E_IVLOPTION
,"Invalid option\n"
"netconf --connect site [ --fore ]"));
}
}
PPPONE *one = ppp_getconfig (argc,argv);
if (one != NULL){
ret = one->connect (fore);
delete one;
}
return ret;
}
/*
Kill a PPP/SLIP connnection
*/
int ppp_disconnect (int argc, char *argv[])
{
int ret = -1;
PPPONE *one = ppp_getconfig (argc,argv);
if (one != NULL){
ret = one->disconnect ();
delete one;
}
return ret;
}